| 特性 | Python列表 | NumPy数组 |
|---|---|---|
| 内存存储 | 分散存储对象引用 | 连续内存存储 |
| 元素类型 | 可以不同 | 必须相同 |
| 性能 | 解释执行,较慢 | 编译优化,极快 |
| 向量化 | 不支持 | 原生支持 |
| 内存效率 | 较低 | 较高(紧凑存储) |
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
import numpy as np # 导入NumPy数值计算库
# 已知股价数据
stock1=np.array([22.91,22.89,23.38,23.09,22.90])
stock2=np.array([41.14,40.99,41.29,40.81,40.97]) # 创建NumPy数组stock2
# 1. 查看股票1的属性值情况,并输出。
print(stock1.shape)
# 2. 输出股票2周二的股价
print(stock2[1])
# 3. 连接股票1与股票2的数据(按照2X5的方式连接),并输出
stock_con=np.concatenate(([stock1],[stock2]),axis=0)
print(stock_con) # 输出两只股票收盘价合并后的2×5矩阵(5,)
40.99
[[22.91 22.89 23.38 23.09 22.9 ]
[41.14 40.99 41.29 40.81 40.97]]
股票1收盘价: [22.91 22.89 23.38 23.09 22.9 ]
股票2收盘价: [41.14 40.99 41.29 40.81 40.97]
数据类型: float64
object:输入数据(列表、元组或其他数组)dtype:指定数据类型(如np.float64、np.int32)copy:是否复制数据(默认True)金融数据类型选择:
float64:双精度,金融计算推荐(价格、收益率)float32:节省内存,适合大规模数据int64:整数类型(成交量、日期索引)二维数组形状: (2, 5)
行数: 2
列数: 5
shape属性的维度含义:
(5,):单只股票的时间序列(2, 5):多只股票的时间序列(2, 3, 5):多市场 × 多股票 × 多日(面板数据)[start:end:step]切片规则:start包含,end不包含;负数索引从末尾计数
array[row, col]stocks_2d[0, 2] = 23.38
股票2所有交易日: [41.14 40.99 41.29 40.81 40.97]
周三所有股票价格: [23.38 41.29]
金融应用场景:
arr[stock_id, :]arr[:, day_id]arr[:, start:end]垂直拼接结果:
[[22.91 22.89 23.38 23.09 22.9 ]
[41.14 40.99 41.29 40.81 40.97]]
形状: (2, 5)
扩充后的股票2: [41.14 40.99 41.29 40.81 40.97 22.95 23.02]
垂直堆叠:
[[22.91 22.89 23.38 23.09 22.9 ]
[41.14 40.99 41.29 40.81 40.97]]
水平连接: [22.91 22.89 23.38 23.09 22.9 41.14 40.99 41.29 40.81 40.97]
| 函数 | 功能 | 等价操作 |
|---|---|---|
concatenate |
通用拼接(指定axis) | — |
vstack |
垂直堆叠 | concatenate(..., axis=0) |
hstack |
水平连接 | concatenate(..., axis=1) |
# hsplit:水平分割(按列切分)
stocks_split = np.hsplit(stocks_2d, [2, 4])
print('按列分割结果:')
for i, part in enumerate(stocks_split):
print(f' 部分{i+1}: 形状{part.shape}')
# vsplit:垂直分割(按行切分)
stocks_vsplit = np.vsplit(stocks_2d, 2)
print(f'\n按行分割:')
for i, part in enumerate(stocks_vsplit):
print(f' 部分{i+1}: {part}')按列分割结果:
部分1: 形状(2, 2)
部分2: 形状(2, 2)
部分3: 形状(2, 1)
按行分割:
部分1: [[22.91 22.89 23.38 23.09 22.9 ]]
部分2: [[41.14 40.99 41.29 40.81 40.97]]
[1:4] 返回的是原数组的视图修改副本后,原数组: [1 2 3 4 5]
Fancy索引修改后,原数组: [1 2 3 4 5]
| 操作 | 返回类型 | 是否共享内存 |
|---|---|---|
切片 [start:end] |
视图 | ✅ 是 |
Fancy索引 [[0,2]] |
副本 | ❌ 否 |
布尔索引 [mask] |
副本 | ❌ 否 |
.copy() |
副本 | ❌ 否 |
最佳实践:不确定时,使用 .copy() 避免意外修改
一维数组: [0 1 2 3 4 5 6 7 8 9]
2×5数组:
[[0 1 2 3 4]
[5 6 7 8 9]]
5×2数组:
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
arr_2x5 = np.arange(10).reshape(2, 5)
# ravel():展平为一维(可能返回视图)
flat_ravel = arr_2x5.ravel()
print(f'ravel结果: {flat_ravel}')
# flatten():展平为一维(总是返回副本)
flat_flatten = arr_2x5.flatten()
print(f'flatten结果: {flat_flatten}')
# .T:转置(行列互换)
transpose = arr_2x5.T # 2×5 → 5×2
print(f'\n转置后 {transpose.shape}:\n{transpose}')ravel结果: [0 1 2 3 4 5 6 7 8 9]
flatten结果: [0 1 2 3 4 5 6 7 8 9]
转置后 (5, 2):
[[0 5]
[1 6]
[2 7]
[3 8]
[4 9]]
广播允许不同形状的数组进行算术运算,NumPy会自动扩展较小的数组。
广播规则:
0.9 被自动扩展为 [0.9, 0.9, 0.9, 0.9, 0.9]标准化后的收益率:
[[ 1.22474487 -1.22474487 0. ]
[ 0.98058068 -1.37281295 0.39223227]]
import time
n = 1000000 # 100万个数据点
prices = np.random.randn(n) * 10 + 100 # 模拟股价数据
# 方法1:Python循环(慢)
start = time.time()
returns_loop = []
for i in range(1, len(prices)):
ret = (prices[i] - prices[i-1]) / prices[i-1]
returns_loop.append(ret)
loop_time = time.time() - start
# 方法2:NumPy向量化(快)
start = time.time()
returns_vec = (prices[1:] - prices[:-1]) / prices[:-1]
vec_time = time.time() - start
print(f'循环时间: {loop_time:.4f}秒')
print(f'向量化时间: {vec_time:.4f}秒')
print(f'性能提升: {loop_time/vec_time:.1f}倍')循环时间: 0.3623秒
向量化时间: 0.0034秒
性能提升: 105.3倍
np.array() 从列表创建,支持多维[start:end:step],二维用 [row, col]concatenate/vstack/hstack 与 hsplit/vsplit.copy() 创建独立副本[商业大数据分析与应用]